package com.kds.changzhou.netty;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.kds.changzhou.data.Gateway;
import com.kds.changzhou.handler.HandlerConfig;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 孔德嵩
 */

public class TcpClient {

    public static final AttributeKey GATE_WAY_KEY = AttributeKey.newInstance("GATE_WAY_KEY");

    private final Logger logger = LoggerFactory.getLogger(TcpClient.class);

    private EventLoopGroup group;

    private final HandlerConfig handlerConfig;

    private final Gateway gateway;

    public TcpClient(HandlerConfig handlerConfig, Gateway gateway) {

        this.gateway = gateway;

        this.handlerConfig = handlerConfig;
    }

    private void doConnect() {

        Bootstrap bootstrap = new Bootstrap();
        this.group = new NioEventLoopGroup();
        bootstrap.group(group)
                .channel(NioSocketChannel.class) // 指定Channel类型为NioSocketChannel
                .option(ChannelOption.TCP_NODELAY, true) // 设置TCP相关参数
                .handler(handlerConfig.getChannelInitializer()).
                attr(GATE_WAY_KEY, gateway);

        ChannelFuture future = bootstrap.connect(handlerConfig.getIp(), handlerConfig.getPort());

        future.addListener((ChannelFutureListener) channelFuture -> {

            if (!channelFuture.isSuccess()) {

                logger.info("采集器[{}_{}]连接服务器失败,10秒后重试: {}\n", gateway.getBuildingCode(), gateway.getGatewayId(), ExceptionUtil.getMessage(future.cause()));

                stop(channelFuture.channel());

                Thread.sleep(10000);

                logger.info("采集器[{}_{}]正在尝试重新连接...", gateway.getBuildingCode(), gateway.getGatewayId());
                doConnect();
            } else {
                logger.info("采集器[{}_{}]已连接成功", gateway.getBuildingCode(), gateway.getGatewayId());
            }

        });

    }


    public void start() {

        logger.info("采集器[{}_{}],启动连接服务器 {}:{}", gateway.getBuildingCode(), gateway.getGatewayId(), handlerConfig.getIp(), handlerConfig.getPort());

        doConnect();

    }

    public void stop(Channel channel) {
        channel.closeFuture().addListener(future -> {
            logger.info("关闭与服务器的连接");
            group.shutdownGracefully();
            group = null;
        });
        channel.close();
    }


}
